/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.jSkyRoom.bridge.major;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import ru.jSkyRoom.interfaces.major.Armor;
import ru.jSkyRoom.interfaces.major.Faction;
import ru.jSkyRoom.interfaces.major.FormList;
import ru.jSkyRoom.interfaces.major.HeadPart;
import ru.jSkyRoom.interfaces.major.LeveledItemList;
import ru.jSkyRoom.interfaces.major.Major;
import ru.jSkyRoom.interfaces.major.NPC;
import ru.jSkyRoom.interfaces.major.Outfit;
import ru.jSkyRoom.interfaces.major.Perk;
import ru.jSkyRoom.interfaces.major.Race;
import ru.jSkyRoom.interfaces.major.Spell;
import ru.jSkyRoom.interfaces.major.Texture;
import ru.jSkyRoom.interfaces.stub.AIPackage;
import ru.jSkyRoom.interfaces.stub.AudioTemplate;
import ru.jSkyRoom.interfaces.stub.CombatStyle;
import ru.jSkyRoom.interfaces.stub.JSkyColor;
import ru.jSkyRoom.interfaces.stub.JSkyScriptPackage;
import ru.jSkyRoom.interfaces.stub.NPCClass;
import ru.jSkyRoom.interfaces.stub.VoiceType;
import ru.jSkyRoom.interfaces.sub.FacePart;
import ru.jSkyRoom.interfaces.sub.FaceTint;
import ru.jSkyRoom.interfaces.sub.SkillDescription;
import ru.jSkyRoom.interfaces.sub.Stat;
import skyproc.FormID;
import skyproc.ItemListing;
import skyproc.NPC_;
import skyproc.NPC_.NPCFlag;
import skyproc.NPC_.TemplateFlag;
import skyproc.RGB;
import skyproc.ScriptPackage;
import skyproc.SubFormInt;
import skyproc.genenums.Skill;
import skyproc.genenums.SoundVolume;

/**
 *
 * @author Rakev
 */
public class NPCBridge extends NamedMajorBridge<NPC_> implements NPC {

    public NPCBridge(NPC_ adapting) {
        super(adapting);
    }

    @Override
    public JSkyScriptPackage getScriptPackage() {
        ScriptPackage scriptPackage = getRawObject().getScriptPackage();
        return getBridgeFactory().createBridge(scriptPackage);
    }

    @Override
    public boolean getFlag(TemplateFlag flag) {
        return getRawObject().get(flag);
    }

    @Override
    public void setFlag(TemplateFlag flag) {
        getRawObject().set(flag, true);
    }

    @Override
    public void unsetFlag(TemplateFlag flag) {
        getRawObject().set(flag, false);
    }

    @Override
    public boolean getFlag(NPCFlag flag) {
        return getRawObject().get(flag);
    }

    @Override
    public void setFlag(NPCFlag flag) {
        getRawObject().set(flag, true);
    }

    @Override
    public void unsetFlag(NPCFlag flag) {
        getRawObject().set(flag, false);
    }

    @Override
    public Map<Faction, Integer> getFactions() {
        Collection<SubFormInt> rawFactionRanks = getRawObject().getFactions();
        Map<Faction, Integer> factionRanks = new HashMap<>(rawFactionRanks.size());
        for (SubFormInt factionIDRank : rawFactionRanks) {
            Faction faction = getFinderFactory().createFactionFinder().find(factionIDRank.getForm());
            factionRanks.put(faction, factionIDRank.getNum());
        }
        return Collections.unmodifiableMap(factionRanks);
    }

    @Override
    public void addFaction(Faction faction, int rank) {
        FormID id = getIdProducer().produce(faction);
        getRawObject().addFaction(id, rank);
    }

    @Override
    public void removeFaction(Faction faction) {
        FormID id = getIdProducer().produce(faction);
        getRawObject().removeFaction(id);
    }

    @Override
    public Map<Perk, Integer> getPerks() {
        Collection<SubFormInt> rawPerkRanks = getRawObject().getPerks();
        Map<Perk, Integer> factionRanks = new HashMap<>(rawPerkRanks.size());
        for (SubFormInt factionIDRank : rawPerkRanks) {
            Perk faction = getFinderFactory().createPerkFinder().find(factionIDRank.getForm());
            factionRanks.put(faction, factionIDRank.getNum());
        }
        return Collections.unmodifiableMap(factionRanks);
    }

    @Override
    public void addPerk(Perk faction, int rank) {
        FormID id = getIdProducer().produce(faction);
        getRawObject().addPerk(id, rank);
    }

    @Override
    public void removePerk(Perk faction) {
        FormID id = getIdProducer().produce(faction);
        getRawObject().removePerk(id);
    }

    @Override
    public SkillDescription getSkillDescription(final Skill skill) {
        return new SkillDescription() {

            @Override
            public int getValue() {
                return getRawObject().get(skill);
            }

            @Override
            public void setValue(int value) {
                getRawObject().set(skill, value);
            }

            @Override
            public int getMod() {
                return getRawObject().getMod(skill);
            }

            @Override
            public void setMod(int mod) {
                getRawObject().setMod(skill, mod);
            }

        };
    }

    @Override
    public NPC_.Aggression getAggression() {
        return getRawObject().getAggression();
    }

    @Override
    public void setAggression(NPC_.Aggression level) {
        getRawObject().setAggression(level);
    }

    @Override
    public NPC_.Confidence getConfidence() {
        return getRawObject().getConfidence();
    }

    @Override
    public void setConfidence(NPC_.Confidence level) {
        getRawObject().setConfidence(level);
    }

    @Override
    public NPC_.Morality getMorality() {
        return getRawObject().getMorality();
    }

    @Override
    public void setMorality(NPC_.Morality level) {
        getRawObject().setMorality(level);
    }

    @Override
    public NPC_.Assistance getAssistance() {
        return getRawObject().getAssistance();
    }

    @Override
    public void setAssistance(NPC_.Assistance level) {
        getRawObject().setAssistance(level);
    }

    @Override
    public Stat getStat(final NPC_.NPCStat stat) {
        return new Stat() {

            @Override
            public int getValue() {
                return getRawObject().get(stat);
            }

            @Override
            public void setValue(int value) {
                getRawObject().set(stat, value);
            }

        };
    }

    @Override
    public LeveledItemList getDeathItems() {
        FormID id = getRawObject().getDeathItem();
        return getFinderFactory().createLeveledItemListFinder().find(id);
    }

    @Override
    public void setDeathItems(LeveledItemList deathItems) {
        FormID id = getIdProducer().produce(deathItems);
        getRawObject().setDeathItem(id);
    }

    @Override
    public VoiceType getVoiceType() {
        FormID id = getRawObject().getVoiceType();
        return getFinderFactory().createVoiceTypeFinder().find(id);
    }

    @Override
    public void setVoiceType(VoiceType voiceType) {
        FormID id = getIdProducer().produce(voiceType);
        getRawObject().setVoiceType(id);
    }

    @Override
    public NPC getTemplate() {
        FormID templateFormId = getRawObject().getTemplate();
        return getFinderFactory().createNPCFinder().find(templateFormId);
    }

    @Override
    public void setTemplate(NPC template) {
        FormID id = getIdProducer().produce(template);
        getRawObject().setTemplate(id);
    }

    @Override
    public Race getRace() {
        FormID id = getRawObject().getRace();
        return getFinderFactory().createRaceFinder().find(id);
    }

    @Override
    public void setRace(Race race) {
        FormID id = getIdProducer().produce(race);
        getRawObject().setRace(id);
    }

    @Override
    public Collection<Spell> getSpells() {
        Collection<FormID> ids = getRawObject().getSpells();
        Collection<Spell> spells = getFinderFactory().createSpellFinder().find(ids);
        return Collections.unmodifiableCollection(spells);
    }

    @Override
    public void addSpell(Spell spell) {
        FormID id = getIdProducer().produce(spell);
        getRawObject().addSpell(id);
    }

    @Override
    public void removeSpell(Spell spell) {
        FormID id = getIdProducer().produce(spell);
        getRawObject().removeSpell(id);
    }

    @Override
    public Map<Major, Integer> getItems() {
        Collection<ItemListing> itemListings = getRawObject().getItems();
        Map<Major, Integer> items = new HashMap<>(itemListings.size());
        for (ItemListing itemListing : getRawObject().getItems()) {
            FormID itemID = itemListing.getForm();
            Major item = getFinderFactory().createMajorFinder().find(itemID);
            Integer count = itemListing.getCount();
            items.put(item, count);
        }
        return Collections.unmodifiableMap(items);
    }

    @Override
    public void addItem(Major item, int count) {
        FormID id = getIdProducer().produce(item);
        getRawObject().addItem(id, count);
    }

    @Override
    public void removeItem(Major item) {
        FormID id = getIdProducer().produce(item);
        getRawObject().removeItem(id);
    }

    @Override
    public Collection<AIPackage> getAIPackages() {
        Collection<FormID> ids = getRawObject().getAIPackages();
        Collection<AIPackage> packages = getFinderFactory().createAIPackagesFinder().find(ids);
        return Collections.unmodifiableCollection(packages);
    }

    @Override
    public void addAIPackage(AIPackage aiPackage) {
        FormID id = getIdProducer().produce(aiPackage);
        getRawObject().addAIPackage(id);
    }

    @Override
    public void removeAIPackage(AIPackage aiPackage) {
        FormID id = getIdProducer().produce(aiPackage);
        getRawObject().removeAIPackage(id);
    }

    @Override
    public NPCClass getNPCClass() {
        FormID id = getRawObject().getNPCClass();
        return getFinderFactory().createNPCClassFinder().find(id);
    }

    @Override
    public void setNPCClass(NPCClass npcClass) {
        FormID id = getIdProducer().produce(npcClass);
        getRawObject().setNPCClass(id);
    }

    @Override
    public JSkyColor getHairColor() {
        FormID id = getRawObject().getHairColor();
        return getFinderFactory().createJSkyColorFinder().find(id);
    }

    @Override
    public void setHairColor(JSkyColor hairColor) {
        FormID id = getIdProducer().produce(hairColor);
        getRawObject().setHairColor(id);
    }

    @Override
    public Armor getSkin() {
        FormID id = getRawObject().getSkin();
        return getFinderFactory().createArmorFinder().find(id);
    }

    @Override
    public void setSkin(Armor skin) {
        FormID id = getIdProducer().produce(skin);
        getRawObject().setSkin(id);
    }

    @Override
    public Race getAttackRace() {
        FormID id = getRawObject().getAttackDataRace();
        return getFinderFactory().createRaceFinder().find(id);
    }

    @Override
    public void setAttackRace(Race attackRace) {
        FormID id = getIdProducer().produce(attackRace);
        getRawObject().setAttackDataRace(id);
    }

    @Override
    public Outfit getDefaultOutfit() {
        FormID id = getRawObject().getDefaultOutfit();
        return getFinderFactory().createOutfitFinder().find(id);
    }

    @Override
    public void setDefaultOutfit(Outfit defaultOutfit) {
        FormID id = getIdProducer().produce(defaultOutfit);
        getRawObject().setDefaultOutfit(id);
    }

    @Override
    public Outfit getSleepingOutfit() {
        FormID id = getRawObject().getSleepingOutfit();
        return getFinderFactory().createOutfitFinder().find(id);
    }

    @Override
    public void setSleepingOutfit(Outfit sleepingOutfit) {
        FormID id = getIdProducer().produce(sleepingOutfit);
        getRawObject().setSleepingOutfit(id);
    }

    @Override
    public CombatStyle getCombatStyle() {
        FormID id = getRawObject().getCombatStyle();
        return getFinderFactory().createCombatStyleFinder().find(id);
    }

    @Override
    public void setCombatStyle(CombatStyle combatRef) {
        FormID id = getIdProducer().produce(combatRef);
        getRawObject().setCombatStyle(id);
    }

    @Override
    public Faction getCrimeFaction() {
        FormID id = getRawObject().getCrimeFaction();
        return getFinderFactory().createFactionFinder().find(id);
    }

    @Override
    public void setCrimeFaction(Faction crimeFaction) {
        FormID id = getIdProducer().produce(crimeFaction);
        getRawObject().setCrimeFaction(id);
    }

    @Override
    public Texture getFaceTextures() {
        FormID id = getRawObject().getFeatureSet();
        return getFinderFactory().createTextureFinder().find(id);
    }

    @Override
    public void setFaceTextures(Texture set) {
        FormID id = getIdProducer().produce(set);
        getRawObject().setFeatureSet(id);
    }

    @Override
    public AudioTemplate getAudioTemplate() {
        FormID id = getRawObject().getAudioTemplate();
        return getFinderFactory().createAudioTemplateFinder().find(id);
    }

    @Override
    public void setAudioTemplate(AudioTemplate audioTemplate) {
        FormID id = getIdProducer().produce(audioTemplate);
        getRawObject().setAudioTemplate(id);
    }

    @Override
    public FormList getDefaultPackageList() {
        FormID id = getRawObject().getDefaultPackageList();
        return getFinderFactory().createFormListFinder().find(id);
    }

    @Override
    public void setDefaultPackageList(FormList list) {
        FormID id = getIdProducer().produce(list);
        getRawObject().setDefaultPackageList(id);
    }

    @Override
    public float getWeight() {
        return getRawObject().getWeight();
    }

    @Override
    public void setWeight(float weight) {
        getRawObject().setWeight((float) weight);
    }

    @Override
    public float getHeight() {
        return getRawObject().getHeight();
    }

    @Override
    public void setHeight(float height) {
        getRawObject().setHeight((float) height);
    }

    @Override
    public Armor getFarAwayModelSkin() {
        FormID id = getRawObject().getFarAwayModelSkin();
        return getFinderFactory().createArmorFinder().find(id);
    }

    @Override
    public void setFarAwayModelSkin(Armor skin) {
        FormID id = getIdProducer().produce(skin);
        getRawObject().setFarAwayModelSkin(id);
    }

    @Override
    public float getFarAwayModelDistance() {
        return getRawObject().getFarAwayModelDistance();
    }

    @Override
    public void setFarAwayModelDistance(float dist) {
        getRawObject().setFarAwayModelDistance(dist);
    }

    @Override
    public int getHealthOffset() {
        return getRawObject().getHealthOffset();
    }

    @Override
    public void setHealthOffset(int value) {
        getRawObject().setHealthOffset(value);
    }

    @Override
    public int getMagickaOffset() {
        return getRawObject().getMagickaOffset();
    }

    @Override
    public void setMagickaOffset(int value) {
        getRawObject().setMagickaOffset(value);
    }

    @Override
    public int getStaminaOffset() {
        return getRawObject().getFatigueOffset();
    }

    @Override
    public void setStaminaOffset(int value) {
        getRawObject().setFatigueOffset(value);
    }

    @Override
    public NPC_.Mood getMood() {
        return getRawObject().getMood();
    }

    @Override
    public void setMood(NPC_.Mood value) {
        getRawObject().setMood(value);
    }

    @Override
    public int getStamina() {
        return getRawObject().getEnergy();
    }

    @Override
    public void setStamina(int energy) {
        getRawObject().setEnergy(energy);
    }

    @Override
    public int getAggroWarn() {
        return getRawObject().getAggroWarn();
    }

    @Override
    public void setAggroWarn(int aggro) {
        getRawObject().setAggroWarn(aggro);
    }

    @Override
    public int getAggroWarnAttack() {
        return getRawObject().getAggroWarnAttack();
    }

    @Override
    public void setAggroWarnAttack(int aggro) {
        getRawObject().setAggroWarnAttack(aggro);
    }

    @Override
    public int getAggroAttack() {
        return getRawObject().getAggroAttack();
    }

    @Override
    public void setAggroAttack(int aggro) {
        getRawObject().setAggroAttack(aggro);
    }

    @Override
    public FormList getGiftFilter() {
        FormID id = getRawObject().getGiftFilter();
        return getFinderFactory().createFormListFinder().find(id);
    }

    @Override
    public void setGiftFilter(FormList filter) {
        FormID id = getIdProducer().produce(filter);
        getRawObject().setGiftFilter(id);
    }

    @Override
    public int getGearedUpWeapons() {
        return getRawObject().getGearedUpWeapons();
    }

    @Override
    public void setGearedUpWeapons(int value) {
        getRawObject().setGearedUpWeapons(value);
    }

    @Override
    public FormList getSpectatorOverride() {
        FormID id = getRawObject().getSpectatorOverride();
        return getFinderFactory().createFormListFinder().find(id);
    }

    @Override
    public void setSpectatorOverride(FormList list) {
        FormID id = getIdProducer().produce(list);
        getRawObject().setSpectatorOverride(id);
    }

    @Override
    public FormList getObserveDeadOverride() {
        FormID id = getRawObject().getObserveDeadOverride();
        return getFinderFactory().createFormListFinder().find(id);
    }

    @Override
    public void setObserveDeadOverride(FormList list) {
        FormID id = getIdProducer().produce(list);
        getRawObject().setObserveDeadOverride(id);
    }

    @Override
    public FormList getGuardWarnOverride() {
        FormID id = getRawObject().getGuardWornOverride();
        return getFinderFactory().createFormListFinder().find(id);
    }

    @Override
    public void setGuardWarnOverride(FormList list) {
        FormID id = getIdProducer().produce(list);
        getRawObject().setGuardWornOverride(id);
    }

    @Override
    public FormList getCombatOverride() {
        FormID id = getRawObject().getCombatOverride();
        return getFinderFactory().createFormListFinder().find(id);
    }

    @Override
    public void setCombatOverride(FormList list) {
        FormID id = getIdProducer().produce(list);
        getRawObject().setCombatOverride(id);
    }

    @Override
    public String getShortName() {
        return getRawObject().getShortName();
    }

    @Override
    public void setShortName(String alias) {
        getRawObject().setShortName(alias);
    }

    @Override
    public SoundVolume getSoundVolume() {
        return getRawObject().getSoundVolume();
    }

    @Override
    public void setSoundVolume(SoundVolume vol) {
        getRawObject().setSoundVolume(vol);
    }

    @Override
    public FacePart getFace(final NPC_.FacePart part) {
        return new FacePart() {

            @Override
            public float getValue() {
                return getRawObject().getFaceValue(part);
            }

            @Override
            public void setValue(float value) {
                getRawObject().setFaceValue(part, value);
            }

        };
    }

    @Override
    public Collection<NPC_.TintLayer> getTintings() {
        return Collections.unmodifiableCollection(getRawObject().getTinting());
    }

    @Override
    public void addTinting(NPC_.TintLayer tinting) {
        getRawObject().addTinting(tinting);
    }

    @Override
    public void removeTinting(NPC_.TintLayer tinting) {
        getRawObject().removeTinting(tinting);
    }

    @Override
    public Collection<NPC_.SoundPackage> getSounds() {
        return Collections.unmodifiableCollection(getRawObject().getSounds());
    }

    @Override
    public void addSoundPackage(NPC_.SoundPackage sounds) {
        getRawObject().addSoundPackage(sounds);
    }

    @Override
    public void removeSoundPackage(NPC_.SoundPackage sounds) {
        getRawObject().removeSoundPackage(sounds);
    }

    @Override
    public FaceTint getFaceTint(final RGB color) {
        return new FaceTint() {

            @Override
            public float getValue() {
                return getRawObject().getFaceTint(color);
            }

            @Override
            public void setValue(float value) {
                getRawObject().setFaceTint(color, value);
            }

        };
    }

    @Override
    public int getNosePreset() {
        return getRawObject().getNosePreset();
    }

    @Override
    public void setNosePreset(int val) {
        getRawObject().setNosePreset(val);
    }

    @Override
    public int getEyePreset() {
        return getRawObject().getEyePreset();
    }

    @Override
    public void setEyePreset(int val) {
        getRawObject().setEyePreset(val);
    }

    @Override
    public int getMouthPreset() {
        return getRawObject().getMouthPreset();
    }

    @Override
    public void setMouthPreset(int val) {
        getRawObject().setMouthPreset(val);
    }

    @Override
    public Collection<HeadPart> getHeadParts() {
        Collection<FormID> ids = getRawObject().getHeadParts();
        Collection<HeadPart> parts = getFinderFactory().createHeadPartFinder().find(ids);
        return Collections.unmodifiableCollection(parts);
    }

    @Override
    public void addHeadPart(HeadPart part) {
        FormID id = getIdProducer().produce(part);
        getRawObject().addHeadPart(id);
    }

    @Override
    public void removeHeadPart(HeadPart part) {
        FormID id = getIdProducer().produce(part);
        getRawObject().removeHeadPart(id);
    }

}
